
type PeopleType = {
  weight: number,
  goodsWeight: number,
}
type PeopleGroupType = {
  peopleList: PeopleType[],
  startFloor: number,
  targetFloor: number,
  totalWeight: number,
}

/**
 * v2 去掉性别属性 保留人员的重量、所携带的货物重量
 * @param MaxFloor 最高层
 * @param MinFloor 最底层 // 没有 0 层
 * @param CurrentFloor 可选参数，指定乘员刷新在当前楼层
 * @returns 随机 1-4个值 [{ weight: number, goodWeight: number }]
 */
const createPeopleGroup = (MaxFloor: number, MinFloor: number, CurrentFloor?: number): PeopleGroupType => {

  /**
   * 随机生成乘客初始所在楼层（有现实情况因素影响，非绝对随机）
   * @returns randomFloor: number
   */
  const createStartRandomFloor = (): number => {
    let randomFloor = 0
    let floorRandomRange = []
    for (let i = MinFloor; i <= MaxFloor; i++) {
      if (i !== 0) {
        // 1 楼的概率与其他楼层对半分
        floorRandomRange.push(i)
        floorRandomRange.push(1)
      }
    }
    randomFloor = floorRandomRange[Math.floor(Math.random() * floorRandomRange.length)]
    return randomFloor
  }

  /**
   * 随机生成乘客想要前往的楼层（有现实情况因素影响，非绝对随机）
   * @returns randomFloor: number
   */
  const createTargetRandomFloor = (startFloor: number): number => {
    let arrow = 0 // 乘员所去往楼层相对于当前楼层的方向
    let randomFloor = 0 // 
    let floorRandomRange = [] // 随机楼层的数组
    switch (startFloor) {
      case 1:
        if (MinFloor > 0) {
          arrow = 1 // 如果最低楼层为1楼，则 1 楼乘客只能上楼
        } else {
          arrow = Math.random() > 0.2 ? 1 : -1 // 如果最低楼层不是 1 楼，则乘客上下概率为 4:1
        }
        // 也可以写作这样
        // MinFloor > 0 ? arrow = 1 : Math.random() > 0.2 ? 1 : -1
        break
      case MaxFloor:
        arrow = -1 // 顶楼只能下 且顶楼下到 1 楼的概率较大 
        break
      case MinFloor:
        arrow = 1 // 最底层只能上
        break
      default:
        arrow = Math.random() < 0.2 ? 1 : -1 // 如果是其他楼层，则乘客上下概率为 1:4，且下到 1 楼的 与 上到顶楼的概率大于其他楼层
    }
    if (arrow > 0) { // 乘客向上, startFloor 为小值，targetFloor 为大值
      for (let i = startFloor + 1; i <= MaxFloor; i++) {
        floorRandomRange.push(i)
         // 控制概率，如果初始楼层在 1 层以上，则增加其前往顶楼的概率
        startFloor > 1 && floorRandomRange.push(MaxFloor, MaxFloor)
      }
    } else { // 乘客向下，startFloor 为大值，targetFloor 为小值
      for (let i = startFloor - 1; i >= MinFloor; i--) {
        floorRandomRange.push(i)
        // 控制概率，如果初始楼层在 顶楼，则增加其前往 1 楼 与 1楼以下楼层的概率
        if (startFloor === MaxFloor) {
          for (let j = 1; j >= MinFloor; j--) {
            floorRandomRange.push(j)
          }
        }
      }
    }
    randomFloor = floorRandomRange[Math.floor(Math.random() * floorRandomRange.length)]
    return randomFloor
  }

  // 乘员体重区间 // 小孩体重为 10 - 40kg ll
  const weightRange = [10, 20, 40, 80]
  // 生成的乘员组的乘员数量区间
  const peopleNumberRange = [1, 2, 3, 4, 1, 2, 3, 1, 2, 1]
  // 随机刷新乘员所在的楼层
  const startFloor = CurrentFloor || createStartRandomFloor()
  // 目标楼层，上乘客随机刷新乘员所在楼层的上层楼层（如果是非1楼乘客上楼，则上顶楼概率较大），
  // 下乘客大概率为 1楼和底楼，其他楼层为小概率
  const targetFloor = createTargetRandomFloor(startFloor)

  // 随机组数，其中 1:2:3:4 的比值为 4:3:2:1
  const peopleNumber = peopleNumberRange[Math.floor(Math.random() * peopleNumberRange.length)]
  let peopleList: PeopleType[] = []
  let totalWeight: number = 0

  for (let i = 1; i <= peopleNumber; i ++) {
    let person: PeopleType = {
      weight: 0,
      goodsWeight: 0,
    }
    if (i === 1) { //第1组 （非小孩）
      person.weight = Math.floor((Math.random() * (weightRange[3] - weightRange[2])) + weightRange[2])
      // let hasGoods 
      if (peopleNumber == 1) { //组数为1
        let  hasGoods = Math.random() > 0.6
        person.goodsWeight = hasGoods ? Math.floor(Math.random() * (person.weight > 40 ? 200 : person.weight / 5)) : 0
      } else {
        let hasGoods = Math.random() > 0.8
        person.goodsWeight = hasGoods ? Math.floor(Math.random() * person.weight / 5) : 0
      }
    } else {
      person.weight = Math.floor((Math.random() * (weightRange[3] - weightRange[0])) + weightRange[0])
      // let hasGoods = (Math.random() - (weightRange[2] / 10)) > 0.8
      let hasGoods = ((person.weight - weightRange[1]) * Math.random()) > 50
      person.goodsWeight = hasGoods ? Math.floor(Math.random() * person.weight / 5) : 0
    }
    peopleList.push(person)
  }

  // 涉及到 数组下标尽可能用有语义的变量或者 i 
  for(let n = 0; n < peopleList.length; n++ ){
    totalWeight += peopleList[n].goodsWeight + peopleList[n].weight
  }

  return {
    peopleList,
    startFloor,
    targetFloor,
    totalWeight,
  }
}

export default createPeopleGroup